package com.cryann.mqttserver.mqttProcess;

import com.cryann.mqttserver.exception.MqttException;
import com.cryann.mqttserver.service.MqttSubject;
import com.cryann.mqttserver.service.MsgStoreService;
import io.netty.channel.Channel;
import io.netty.handler.codec.mqtt.MqttMessageType;
import io.netty.handler.codec.mqtt.MqttPublishMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @author cRyann
 * @date 2018/12/20 0020 14:39
 * @description:
 */
@Component
@Slf4j
@ProcessType(MqttMessageType.PUBLISH)
public class Publish implements BasicProcess<MqttPublishMessage> {
    @Autowired
    MqttSubject mqttSubject;
    @Autowired
    MsgStoreService msgStoreService;

    @Override
    public void process(Channel ctx, MqttPublishMessage message) throws MqttException {
//        MARK CleanSession
//        服务端的会话状态包括：
//        会话是否存在，即使会话状态的其它部分都是空。
//        客户端的订阅信息。
//        已经发送给客户端，但是还没有完成确认的QoS 1和QoS 2级别的消息。
//        即将传输给客户端的QoS 1和QoS 2级别的消息。
//        已从客户端接收，但是还没有完成确认的QoS 2级别的消息。
//        可选，准备发送给客户端的QoS 0级别的消息。
        switch (message.fixedHeader().qosLevel()) {
            // Qos=0
            case AT_MOST_ONCE:
                mqttSubject.publicSub(msgStoreService.conversionMsg(ctx, message));
                break;
            // Qos=1
            case AT_LEAST_ONCE:
                //保存 && 发送
                mqttSubject.publicSub(msgStoreService.storeMsg(ctx, message));
                //应答
                mqttSubject.pubAck(ctx, message);
                break;
            // Qos=2
            case EXACTLY_ONCE:
                //保存
                msgStoreService.storeMsg(ctx, message);
                //PUBREC返回
                mqttSubject.pubrec(ctx, message);
                //MARK 另类处理PUBREL
                //MARK 另类发送PUBLISH
                //MARK 另类处理PUBCOMP
                //MARK 另类处理PUBREC
                //MARK 另类处理PUBCOMP
                break;
            default:
                break;
        }

    }
}
